/*
 * @Author: ipk518 121206530@qq.com
 * @Date: 2023-11-20 09:03:03
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2023-11-22 16:47:02
 * @FilePath: /moduleTest/src/mem.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include "mem.h"
#include "myLog.h"

#define PAGE_SIZE  ((size_t)getpagesize())
#define PAGE_MASK ((uint64_t) (long)~(PAGE_SIZE - 1))

/**
 * @description: 32位写内存
 * @param {unsigned long} phyAddr
 * @param {uint32_t} val
 * @return {*}
 */
void memIn32(unsigned long phyAddr, uint32_t val)
{
	int fd;
	volatile void *mapBase;
	unsigned long base = phyAddr & PAGE_MASK;
	unsigned long pgOffset = phyAddr & (~PAGE_MASK);
	if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
	{
		qlog_e("open /dev/mem:");
		return;
	}
	//虚拟化实际地址（转换实际地址在linux下的虚拟地址）
	mapBase = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
			fd, base);
	if(mapBase == MAP_FAILED)
	{
		qlog_e("mmap:");
		close(fd);
		return;
	}
	// qlog_i("base :%#x,pgOffset:%#x, val:%#x", base, pgoffset, val);
	//直接按照指针的方式复制或者读取
	*(volatile uint32_t*)((uint8_t *) mapBase + pgOffset) = val; 
	munmap((void *)mapBase, PAGE_SIZE);
	close(fd);
}

/**
 * @description: 32位读内存
 * @param {uint64_t} phyAddr
 * @return {*}
 */
int memOut32(uint64_t phyAddr)
{
	int fd;
	uint32_t val;
	volatile void *mapBase;
	uint64_t base = phyAddr & PAGE_MASK;
	uint64_t pgOffset = phyAddr & (~PAGE_MASK);
	//open /dev/mem
	if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
	{
		qlog_e("open /dev/mem:");
		return -1;
	}
	val = getpagesize();
	//mmap
	mapBase = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
			fd, base);
	if(mapBase == MAP_FAILED)
	{
		qlog_e("mmap:");
		close(fd);
		return -1;
	}
	val = *(volatile uint32_t *)((unsigned long *) mapBase + pgOffset);
	munmap((void *)mapBase, PAGE_SIZE);
 	close(fd);
	return val;
}